<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> 
        实现 debounce / throttle  封装节流防抖函数  </title>
</head>
<body>
    
</body>
</html>
<script>
/*  
    throttle节流 drag改变浏览器的大小，触发onsize函数 实现拖动每过1s输出一次，不足1s，1s后输出一次，
多用于高频操作，如抢票，抢购等。无论点击多少次,只固定间隔执行一次，以减轻压力  
    原理：设置canRun作为是否执行的标志.每次触发onresize,都判断canRun的值(true执行/false不执行) 
          第一次应该执行，所有设置canRun初始值维true
          当第一次执行后，设置canRun为false(防止下次执行)，并设置计时器，以恢复canRun的值 
*/
window.canRun = true;
window.throttle = function(callback,time){
    if(!window.canRun){
        return;
    }
    window.canRun = false;
    setTimeout(function(){
        callback()
        window.canRun = true;
    },time)
}
//use 
    window.onresize = function(){
        window.throttle(function(){
            console.log("this is throttle")
        },100)
    }    


/*
    debounce防抖 drag改变浏览器的大小，触发onresize函数，实现拖动停顿1s输出
多用于输入框，当某一次输入后停顿满n秒才会去执行远程搜索 
    原理:timer作为定时器，每次出发onresize事件，都清一下定时器，(之前未执行的drag方法就不会再执行)
         新的定时器在1s后执行方法，那么如果下次drag在1s内，这次赋值的定时器又会被清除(搜索方法不会执行)
         直到下次drag相对于这次drag间隔时间大于1s (定时器时间没有那么准确) 
         再执行一次方法onresize 
*/
timer = false;
debounce = function(callback,time){
    clearTimeout(timer)
    timer = setTimeout(callback,time);
}    
onresize = function(){
    debounce(()=>{console.log('腿不抖了')},100)
}





// 防抖
// 防抖要解决的问题：阻止一个事件被频繁触发。
// 例如：
//      当我们监听浏览器的滚动条事件时，如果不做防抖，就会发生滚动一次鼠标滚轮，事件被触发6-8次。
// 应用场景：等用户的鼠标滚轮滚动到某一个地方，停止滚动1秒之后才执行函数。
// 解决思路：设置一个触发函数执行的「等待时间」，当「等待时间」结束之后才可以被执行。

function debounce(fn, wait) {
  var timer = null;
  return function () {
      var context = this
      var args = arguments
      if (timer) {
          clearTimeout(timer);
          timer = null;
      }
      timer = setTimeout(function () {
          fn.apply(context, args)
      }, wait)
  }
}
var fn = function () {
  console.log('boom')
}
setInterval(debounce(fn,500),1000)  // 第一次在1500ms后触发，之后每1000ms触发一次
setInterval(debounce(fn,2000),1000) // 不会触发一次（我把函数防抖看出技能读条，如果读条没完成就用技能，便会失败而且重新读条）


// 节流
// 节流要解决的问题：和防抖一样，都是阻止一个事件被频繁触发
// 区别：防抖是「等待时间」结束之后再执行函数，而节流是先执行函数，然后再计时，确保计时没有结束之前函数不会再次执行。
// 应用场景：用户在网页的Input表单输入框中按住了某一个按键，但是我们要做到函数不被连续触发，而是每1秒执行1次
function throttle(fn, gapTime) {
  let _lastTime = null;
  return function () {
    let _nowTime = + new Date()
    if (_nowTime - _lastTime > gapTime || !_lastTime) {
      fn();
      _lastTime = _nowTime
    }
  }
}
let fn = ()=>{
  console.log('boom')
}
setInterval(throttle(fn,1000),10)


















</script>